/*
 * Copyright (c) 2009 by ZDO Corporation.
 * Author: A. Onur Cinar
 * 
 * http://code.google.com/p/zdo-struts2
 * http://www.zdo.com
 * 
 * This file is part of ZDO Struts 2 Applications.
 *
 * ZDO-Struts2 is free software: you can redistribute it and/or
 * modify it under the terms of  the GNU General Public License
 * as published by the Free Software Foundation, either version
 *  3 of the License, or any later version.
 *
 * ZDO-Struts2 is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 */

package com.zdo.security;

import java.util.Collection;
import java.util.Map;

import com.opensymphony.xwork2.ActionContext;

/**
 * Security context. Security context lives in a session. An action can get 
 * the security context by either implementing {@link SecurityAware}
 * interface or my invoking the {@link #getContext()} static method.
 * 
 * Example:
 * 
 * <pre>
 * SecurityContext securityContext = SecurityContext.getContext();
 * </pre>
 */
public class SecurityContext
{
	public static final String SESSION_KEY =
		SecurityContext.class.getName().concat(".SESSION_KEY");
	
	private String user;
	private Collection<String> roles;
	
	/**
	 * Gets the security context from the current session. If the
	 * security context does not exit, a new security context
	 * will be returned.
	 * 
	 * @return security context.
	 * @throws IllegalStateException if the action context is null.
	 * @see #getContext(Map)
	 */
	public static SecurityContext getContext () throws IllegalStateException
	{
		ActionContext actionContext = ActionContext.getContext();
		if (actionContext == null)
			throw new IllegalStateException("Action context is null.");
		
		return getContext(actionContext.getSession());
	}
	
	/**
	 * Gets the security context from the given session. If the
	 * security context does not exist, a new security context
	 * will be returned.
	 * 
	 * @param session session map.
	 * @return security context.
	 * @see #getContext()
	 */
	public static SecurityContext getContext (Map<String, Object> session)
	{
		SecurityContext securityContext = (SecurityContext) session.get(SESSION_KEY);
		if (securityContext == null)
		{
			securityContext = new SecurityContext();
			session.put(SESSION_KEY, securityContext);
		}
		
		return securityContext;		
	}
	
	/**
	 * Gets the currently logged in user.
	 * 
	 * @return current user.
	 */
	public String getUser ()
	{
		return user;
	}
	
	/**
	 * Is the user currently logged in.
	 * 
	 * @return <code>true</code> if logged in, <code>false</code> otherwise.
	 */
	public boolean isLoggedIn ()
	{
		return (user != null);
	}
	
	/**
	 * Checks if user is in the given role.
	 * 
	 * @param role user role.
	 * @return <code>true</code> if user is in role, <code>false</code> otherwise.
	 */
	public boolean isInRole (String role)
	{
		if (roles == null)
			return false;
		
		return roles.contains(role);
	}
		
	/**
	 * Login the given user.
	 * 
	 * @param user current user.
	 * @param roles user roles.
	 */
	public void login (String user, Collection<String> roles)
	{
		this.user = user;
		this.roles = roles;
	}
	
	/**
	 * Logout the current user.
	 */
	public void logout ()
	{
		user = null;
		roles = null;
	}
}
